package com.itcat.autoconfig.template;

import com.itcat.autoconfig.properties.AppProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

/**
 * [一句话描述该类的功能]
 *
 * @author : [Cr Mr]
 * @version : [v1.0]
 * @date : [2022/3/30 12:42]
 */
@Slf4j
public class AppTemplate {
    private AppProperties appProperties;

    public AppTemplate(AppProperties appProperties) {
        this.appProperties = appProperties;
    }

    /***
     * Desc:    检查文件
     * @param multiFile
     * @return {@link boolean}
     * @author Cr Mr
     * @date 2022/3/21 15:16
     */
    public boolean checkFile(MultipartFile multiFile) {
        String fileName = multiFile.getName();
        //1.文件是否为空
        if (multiFile.isEmpty()) {
            log.info(fileName + "文件为空");
            return false;
        }
        //内容类型
        String contentType = multiFile.getContentType();
        //文件字节长度
        long size = multiFile.getSize();
        log.info("收到的请求文件信息：原生文件名：{},文件类型：{},文件大小：{}", fileName, contentType, size);
        //获取文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        //2.判断配置的文件列表里是否支持该文件类型
        if (!ArrayUtils.contains(appProperties.getFileTypeArray(), suffix)) {
            log.info("不支持该类型文件上传");
            return false;
        }
        //转化单位为kb
        double fileSize = size / 1024.0;
        //3.判断文件大小是否超过限制
        if (fileSize > appProperties.getMaxFileSize()) {
            log.info("文件大小超过限制");
            return false;
        }
        return true;
    }


    /**
     * 新文件上传
     *
     * @param multiFile      文件
     * @param uploadPath     服务器上要存储文件的路径
     * @param uploadFileName 服务器上要存储的文件的名称
     * @return
     */
    public String upload(MultipartFile multiFile, String uploadPath, String uploadFileName) throws IOException {
        //获取文件输入流
        BufferedInputStream bis = new BufferedInputStream(multiFile.getInputStream());
        String uploadFile = uploadFile(uploadPath, uploadFileName, bis);
        return uploadFile;
    }


    /**
     * 上传文件
     *
     * @param ftpPath  ftp文件存放物理路径
     * @param fileName 文件名称
     * @param input    文件输入流，即从本地服务器读取文件的IO输入流
     */
    public String uploadFile(String ftpPath, String fileName, InputStream input) throws IOException {
        String uploadPath = appProperties.getFtpPath();
        String httpdHost = appProperties.getHttpdHost();
        if (ftpPath != null && !"".equals(ftpPath)) {
            uploadPath = uploadPath + "/" + ftpPath;
            httpdHost = httpdHost + ftpPath;
        }
        FTPClient ftp = getFTPClient();
        ftp.makeDirectory(uploadPath);
        ftp.changeWorkingDirectory(uploadPath);
        //被动传输模式
        ftp.enterLocalPassiveMode();
        ftp.setFileType(FTP.BINARY_FILE_TYPE);
        fileName = new String(fileName.getBytes("GBK"), StandardCharsets.ISO_8859_1);
        ftp.storeFile(fileName, input);
        input.close();
        ftp.logout();
        log.info("upload success!");
        return httpdHost + "/" + fileName;
    }


    /**
     * 获取FTPClient对象
     *
     * @return
     */
    public FTPClient getFTPClient() {
        FTPClient ftpClient = null;
        try {
            //创建一个ftp客户端
            ftpClient = new FTPClient();
            // 连接FTP服务器
            ftpClient.connect(appProperties.getFtpHost(), appProperties.getFtpPort());
            // 登陆FTP服务器
            ftpClient.login(appProperties.getFtpUserName(), appProperties.getFtpPassword());

            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                log.info("未连接到FTP，用户名或密码错误。");
                ftpClient.disconnect();
            } else {
                log.info("FTP连接成功。");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            log.info("FTP的IP地址可能错误，请正确配置。");
        } catch (IOException e) {
            e.printStackTrace();
            log.info("FTP的端口错误,请正确配置。");
        }
        return ftpClient;
    }
}
